package cn.jbolt.wechat.api;

import cn.jbolt.core.api.*;
import cn.jbolt.wechat.cache.JBoltWechatConfigCache;
import cn.jbolt.wechat.cache.JBoltWechatUserCache;
import cn.jbolt.wechat.common.JBoltWechatApi;
import cn.jbolt.wechat.common.WechatApiResult;
import cn.jbolt.wechat.common.mp.WechatMpContext;
import cn.jbolt.wechat.model.WechatUser;
import cn.jbolt.wechat.service.JBoltWechatUserService;
import com.jfinal.aop.Inject;
import com.jfinal.core.Path;
import com.jfinal.core.paragetter.Para;
import com.jfinal.kit.Kv;
import com.jfinal.kit.Ret;
import me.chanjar.weixin.common.bean.WxOAuth2UserInfo;
import me.chanjar.weixin.common.bean.oauth2.WxOAuth2AccessToken;

/**
 * 内置微信公众平台API
 *
 * @ClassName: JBoltWechatApiController
 * @author: JFinal学院-小木 QQ：909854136
 * @date: 2021年5月22日
 */
@Path("/api/wechat")
public class JBoltWechatApiController extends JBoltApiBaseController {
    @Inject
    private JBoltWechatUserService wechatUserService;

    /**
     * 获取公众号h5跳转授权URL
     *
     * @param scope
     */
    @UnCheckJBoltApi
    public void authorize(@Para(value = "scope", defaultValue = "snsapi_userinfo") String scope, @Para("redirectUri") String redirectUri,@Para("state") String state) {
//        String redirect_uri = JBoltHttpSchemeKit.getFull() + JBoltConfig.DOMAIN + "/api/wechat/authCallback?jboltappid=" + JBoltApiKit.getAppId();
        String wechatAppId = JBoltApiKit.getWechatAppId();
        WechatApiResult<String> result = JBoltWechatApi.use(wechatAppId).call(() -> WechatMpContext.buildAuthorizationUrl(redirectUri, scope, state));
        if (notOk(result.getData())) {
            renderJBoltApiFail("生成授权URL失败");
            return;
        }
        renderJBoltApiSuccessWithData(result.getData());
    }

    /**
     * 授权成功回调
     */
    @UnCheckJBoltApi
    public void authCallback(@Para("code") String code, @Para("state") String state) {
        if (notOk(code)) {
            renderJBoltApiFail("授权回调失败，没有获取到code");
            return;
        }
        String wechatAppId = JBoltApiKit.getWechatAppId();
        String secret = JBoltWechatConfigCache.me.getAppSecret(JBoltApiKit.getApplicationLinkTargetId());
        WechatApiResult<WxOAuth2AccessToken> res = JBoltWechatApi.use(wechatAppId).call(() -> WechatMpContext.getAccessToken(wechatAppId, secret, code));
        if (!res.isSuccess()) {
            renderJBoltApiFail("授权回调失败，" + res.getMsg());
            return;
        }
        WxOAuth2AccessToken token = res.getData();
        //拿到openId
        String openId = token.getOpenId();
        Long mpId = JBoltApiKit.getWechatMpId();
        //判断是否存在用户信息
        WechatUser wechatUser = JBoltWechatUserCache.me.getApiWechatUserByMpOpenId(mpId, openId);
        //执行获取用户信息
        WechatApiResult<WxOAuth2UserInfo> userRes = JBoltWechatApi.use(wechatAppId).call(() -> WechatMpContext.getAuthUserInfo(token));
        if (!userRes.isSuccess()) {
            renderJBoltApiFail("授权回调获取用户信息失败，" + userRes.getMsg());
            return;
        }

        Ret ret = null;
        if (wechatUser == null) {
            ret = wechatUserService.addUnSubscribeWechatUserInfo(mpId, openId, userRes.getData());
        } else {
            ret = wechatUserService.updateSubscribeWechatUserInfo(mpId, wechatUser.getId(), userRes.getData());
        }

        if (ret.isFail()) {
            renderText("授权回调创建用户信息失败，" + ret.getStr("msg"));
            return;
        }
        wechatUser = ret.getAs("data");

        //用户存在的话 设置到threadLocal中拦截器得 用
        JBoltApiUser apiUser = JBoltApiKit.processBindUser(
                new JBoltApiUserBean(JBoltApiKit.getApplicationId(), wechatUser.getId(), wechatUser.getNickname(), null),
                wechatUser.getBindUsers());
        //创建JWT
        String[] jwts = JBoltApiJwtManger.me().createJBoltApiTokens(JBoltApiKit.getApplication(), apiUser, 7200000L, 604800000L);
        if (notOk(jwts)) {
            renderText("授权回调创建用户令牌失败");
            return;
        }

//        //将jwt放在响应里
//        set(JBoltApiJwtManger.JBOLT_API_TOKEN_KEY, jwts[0]);
//        //将refreshjwt放在响应里
//        set(JBoltApiJwtManger.JBOLT_API_REFRESH_TOKEN_KEY, jwts[1]);
        renderJBoltApiSuccessWithData(Kv.by(JBoltApiJwtManger.JBOLT_API_TOKEN_KEY, jwts[0]).set(JBoltApiJwtManger.JBOLT_API_REFRESH_TOKEN_KEY,jwts[1]));
    }

}
